---------------------------------------------------------------------------
---------------------------------------------------------------------------
-- Company     : EIA / HTA 
-- Author      : Yves Peissard <ypeissard@gmail.com>
-- 
-- Creation Date : 23/04/2009
-- File          : buttonHandler.vhdl
--
-- Abstract : This is the buttonHandler of the iTimer project.
--			  It checks if the buttonInput was pressed longer than a
--            given time maxTime.
--
--            If buttonInput was pressed longer than maxTime, we send 
--            a logical 1 to the longPush output.
--
--			  If buttonInput was not pressed longer than maxTime, we 
--            send a logical 1 to the simplePush output.
--
--			  Inputs:
--			  buttonInput : std_logic, input received from the mainbutton
--			  clockInput  : std_logic, clock signal
--	
--			  Outputs:
--			  simplePush  : std_logic, 1 if mainbutton not pressed
--                                     longer than maxTime
--
--			  longPush	  : std_logic, 1 if mainbutton pressed 
--						               longer than maxTime
--
---------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


---------------------------------------------------------------------------
entity buttonHandler is 
---------------------------------------------------------------------------
port (
	buttonInput : in STD_LOGIC ;
	clockInput : in STD_LOGIC; 
   simplePush : out STD_LOGIC := '0';
	longPush : out STD_LOGIC := '0');
end buttonHandler;


---------------------------------------------------------------------------
architecture buttonHandler_arch of buttonHandler is
---------------------------------------------------------------------------
	-- internal signals

	-- FIXME: at the final implementation we need to have a larger 
	--        busWaitedTime because 9 downto 0 
	--        is not enought for 1.5 sec
	signal busWaitedTime: std_logic_vector (11 downto 0) := "000000000000" ;
	signal reStartTime  : std_logic := '1';   
	signal simplePush_intern : std_logic := '0';
	signal longPush_intern : std_logic := '0' ;

	-- TODO: set maxTime to the 1500ms specified
	-- in our architecture documentation
	-- but for testing the code we had to set it
	-- to a small value that we don't have
    -- to wait too long each time we compile	
	signal maxTime : integer := 1500;
	signal isLongPushed : std_logic := '0';
	signal old_isLongPushed : std_logic := '0';
	signal old_buttonInput: std_logic := '0';
	

begin --architecture
    
	-- instantiate waitedTime:
	i_waitedTime:entity work.waitedTime
	port map (
		clockInput    => clockInput,
		reStartTime   => reStartTime,
		busWaitedTime => busWaitedTime
	);

	
	main_process : process (clockInput,buttonInput)
	begin
		-- just do something if he have a rising clock event
		if (clockInput'event and clockInput = '1') then
			
			-- be sure that we only have reStartTime
			-- at 1 during one clock cycle
			if (reStartTime = '1') then
				reStartTime <= '0';
			end if;

			-- if we detect a rising edge of buttonInput
			-- we set reStartTime at 1
			-- we need to set isLongPushed to 1 here,
			-- so we can make sure that we only send one
			-- longPush while the user keeps pressing the
			-- button for 10 seconds for example
			if (buttonInput = '1' and old_buttonInput = '0' ) then
				reStartTime <= '1';
				if (old_isLongPushed = '0') then
					isLongPushed <= '1';
				end if;

			-- else if we have a falling edge of buttonInput
			elsif (old_buttonInput = '1' and buttonInput = '0') then
				reStartTime <= '1';
				

				-- if busWaitedTime is smaller than maxTime
				-- we set simplePush at 1 and we set reStartTime at 1
				if (conv_integer(busWaitedTime) < maxTime) then
					simplePush_intern <= '1';
					simplePush <= '1';
					if (old_isLongPushed = '1') then
					    isLongPushed <= '0';
					end if;
				end if;

				-- make sure that we only have longPush
				-- at 1 during one clock cycle
				
					
				
			end if;
			
			
			

			-- make sure that we only have simplePush
			-- at 1 during one clock cycle
			if (simplePush_intern = '1') then
				simplePush_intern <= '0';
				simplePush <= '0';
			end if;
			
			-- make sure that we only have longPush
			-- at 1 during one clock cycle
			if (longPush_intern = '1') then
				longPush_intern <= '0';
				longPush <= '0';
			end if;
			
			

			-- if busWaitedTime is greater than maxTime and isLongPushed is at 0
			if (conv_integer(busWaitedTime) > maxTime and old_isLongPushed = '1') then
				longPush_intern <= '1';
				isLongPushed <= '0';
				longPush <= '1';
			end if;
		
		-- update old_buttonInput, that we can check
		-- for it at the next clock cycle
		old_isLongPushed <= isLongPushed;
		old_buttonInput <= buttonInput;
		end if;
	end process main_process;
	
end buttonHandler_arch;
